﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Mani.Common.Security;
using System.Web.Security;

namespace Mani.Common.UI
{
    /// <summary>
    /// User Management Page
    /// </summary>
    /// <remarks>
    /// Very Weird bug happening on the server regarding ViewState of GridView.Datakeys after PageIndexChange being Empty!
    /// http://forums.asp.net/t/1020478.aspx/1?GridView+DataKeys+Array+is+Empty
    /// http://www.google.com/search?q=GridView+DateKeys+Empty+after+page+index+change&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:en-US:official&client=firefox-a#pq=gridview+datakeys.count++0&hl=en&cp=27&gs_id=3a&xhr=t&q=GridView+DataKeys+ViewState&qe=R3JpZFZpZXcgRGF0YUtleXMgVmlld1N0YXRl&qesig=6Gzp5qKFCtWGOR20mCazkg&pkc=AFgZ2tklQd7jOa5y4TiJg37cDyJibOgf0Y7I0wVc3ZDEmqvyq1xLMqRRCB84TX3pX4RmlJEgTOwX9fo4O1lcb8gRh_33WCh7Yg&pf=p&sclient=psy-ab&client=firefox-a&rls=org.mozilla:en-US%3Aofficial&source=hp&pbx=1&oq=GridView+DataKeys+ViewState&aq=f&aqi=&aql=&gs_sm=&gs_upl=&bav=on.2,or.r_gc.r_pw.,cf.osb&fp=84c58f105e12c753&biw=1920&bih=880
    /// </remarks>
    public partial class UsersPage : AuthorizedPage
    {
        private const String DEFAULT_APPLICATION_ID = "E6ED2728-D5C7-45FC-8183-52A6C624E311";

        public ISecurityManager securityManager { get; set; }

        protected void Page_Load(object sender, EventArgs e)
        {
            if (securityManager == null)
            {
                securityManager = new SecurityManager();
                securityManager.authProvider = new WebAuthorizationProvider();
            }

            if (!Page.IsPostBack)
            {
                LoadApplications();
                LoadRoles();
                gvUsers.DataBind();
            }
        }

        #region grid view events

        protected void gvUsers_DataBinding(object sender, EventArgs e)
        {
            if (ddlApplications.SelectedValue == DEFAULT_APPLICATION_ID)
                return;

            gvUsers.DataKeyNames = new string[] { "UserName" };
            gvUsers.DataSource = securityManager.GetUsersByApplicationId(Guid.Parse(ddlApplications.SelectedValue));
        }

        protected void gvUsers_PageIndexChanging(object sender, GridViewPageEventArgs e)
        {
            if (e.NewPageIndex >= 0 && e.NewPageIndex < gvUsers.PageCount)
            {
                gvUsers.PageIndex = e.NewPageIndex;
                gvUsers.DataBind();
            }
        }

        protected void gvUsers_RowCreated(object sender, GridViewRowEventArgs e)
        {
            if (e.Row.RowType != DataControlRowType.DataRow)
                return;

            LinkButton btnDelete = (LinkButton)e.Row.FindControl("btnDelete");
            if (btnDelete == null) return;

            btnDelete.OnClientClick = "javascript:var result = confirm('آیا نسبت به غیرفعال کردن کاربر مطمئن هستید');if(result==false) { return false };";
        }

        protected void gvUsers_RowDeleting(object sender, GridViewDeleteEventArgs e)
        {
            string username = gvUsers.DataKeys[e.RowIndex].Value.ToString();
            securityManager.DeleteUser(username);
            gvUsers.DataBind();
            ClearForm();
        }

        protected void gvUsers_SelectedIndexChanging(object sender, GridViewSelectEventArgs e)
        {
            ClearForm();
            gvUsers.DataBind();

            string username = gvUsers.DataKeys[e.NewSelectedIndex].Value.ToString();
            aspnet_Users user = securityManager.GetUserInfo(username);

            txtUserName.Text = username;
            txtUserName.ReadOnly = true;
            txtUserEmail.Text = user.aspnet_Membership.Email;
            txtSecurityQuestion.Text = user.aspnet_Membership.PasswordQuestion;
            txtSecurityQuestionAnswer.Text = user.aspnet_Membership.PasswordAnswer;
            cbIsLockedOut.Checked = user.aspnet_Membership.IsLockedOut;
            cbIsApproved.Checked = user.aspnet_Membership.IsApproved;
            ListItem app = ddlUserApplication.Items.FindByValue(user.ApplicationId.ToString());
            if (app != null)
                app.Selected = true;

            foreach (var role in user.aspnet_Roles)
            {
                ListItem item = cbUserRoles.Items.FindByValue(role.RoleName);
                if (item != null)
                    item.Selected = true;
            }
        }

        #endregion

        private void LoadApplications()
        {
            ddlApplications.DataSource = securityManager.GetApplications();
            ddlApplications.DataBind();

            ddlUserApplication.DataSource = securityManager.GetApplications();
            ddlUserApplication.DataBind();
        }

        private void LoadRoles()
        {
            cbUserRoles.Items.Clear();

            if (ddlApplications.SelectedValue == DEFAULT_APPLICATION_ID)
                return;

            List<aspnet_Roles> roles = new List<aspnet_Roles>();
            roles = securityManager.GetRolesByApplication(Guid.Parse(ddlApplications.SelectedValue));
            cbUserRoles.DataSource = roles;
            cbUserRoles.DataBind();
        }

        private void ClearForm()
        {
            txtPassword.Text = String.Empty;
            txtPasswordRepeat.Text = String.Empty;
            txtUserEmail.Text = String.Empty;
            txtUserName.Text = String.Empty;
            txtSecurityQuestion.Text = String.Empty;
            txtSecurityQuestionAnswer.Text = String.Empty;
            txtUserName.ReadOnly = false;
            cbUserRoles.ClearSelection();
            cbIsLockedOut.Checked = false;
            cbIsApproved.Checked = false;
        }

        protected void btnSave_Click(object sender, EventArgs e)
        {
            MembershipProvider provider = Membership.Providers[ddlUserApplication.SelectedItem.Text];
            if (provider == null)
            {
                UIHelper.ClientAlert(this.Page, "بانک اطلاعاتی سیستم انتخاب شده در فایل وب کانفیگ ثبت نشده است");
                return;
            }

            if (txtUserName.ReadOnly)
                Update();
            else
                New();
        }

        private void Update()
        {
            aspnet_Users user = securityManager.GetUserInfo(txtUserName.Text);

            user.aspnet_Membership.Email = txtUserEmail.Text;
            user.aspnet_Membership.LoweredEmail = txtUserEmail.Text.ToLower();
            user.aspnet_Membership.IsLockedOut = cbIsLockedOut.Checked;
            user.aspnet_Membership.IsApproved = cbIsApproved.Checked;
            user.aspnet_Membership.ApplicationId = Guid.Parse(ddlUserApplication.SelectedValue);
            user.aspnet_Membership.PasswordQuestion = txtSecurityQuestion.Text;
            user.aspnet_Membership.PasswordAnswer = txtSecurityQuestionAnswer.Text;

            user.ApplicationId = Guid.Parse(ddlUserApplication.SelectedValue);

            if (!String.IsNullOrEmpty(txtPassword.Text))
                securityManager.UpdatePassword(user.UserName, txtPassword.Text, ddlUserApplication.SelectedItem.Text);


            foreach (ListItem item in cbUserRoles.Items)
            {
                List<aspnet_Roles> roles = new List<aspnet_Roles>();
                roles.Add(securityManager.GetRoleById(Guid.Parse(item.Value)));

                if (item.Selected)
                {
                    if (!securityManager.IsUserinRole(user.UserName, item.Text))
                    {
                        securityManager.AddUserToRoles(user, roles);
                    }
                }
                else if (securityManager.IsUserinRole(user.UserName, item.Text))
                {
                    securityManager.RemoveUserFromRoles(user, roles);
                }
            }

            securityManager.SaveChanges();
            UIHelper.ClientAlert(this.Page, "تغییرات با موفقیت ذخیره شد");
            ClearForm();
            gvUsers.DataBind();
        }

        private void New()
        {
            MembershipCreateStatus status;
            aspnet_Users user = securityManager.CreateUser(txtUserName.Text, txtPassword.Text, txtUserEmail.Text, ddlUserApplication.SelectedItem.Text, txtSecurityQuestion.Text, txtSecurityQuestionAnswer.Text, cbIsApproved.Checked, out status);

            if (status != MembershipCreateStatus.Success)
            {
                UIHelper.ClientAlert(this.Page, UIHelper.GetFriendlyErrorForMembershipFailure(status));
                return;
            }

            List<aspnet_Roles> roles = new List<aspnet_Roles>();

            foreach (ListItem item in cbUserRoles.Items)
            {
                if (item.Selected)
                    roles.Add(securityManager.GetRoleById(Guid.Parse(item.Value)));
            }

            securityManager.AddUserToRoles(user, roles);
            securityManager.SaveChanges();
            UIHelper.ClientAlert(this.Page, "تغییرات با موفقیت ذخیره شد");
            ClearForm();
            gvUsers.DataBind();
        }

        protected void ddlUserApplication_SelectedIndexChanged(object sender, EventArgs e)
        {
            ddlApplications.ClearSelection();
            ddlApplications.Items.FindByValue(ddlUserApplication.SelectedValue).Selected = true;
            LoadRoles();
            gvUsers.DataBind();
        }

        protected void ddlApplications_SelectedIndexChanged(object sender, EventArgs e)
        {
            ddlUserApplication.ClearSelection();
            ddlUserApplication.Items.FindByValue(ddlApplications.SelectedValue).Selected = true;
            LoadRoles();
            gvUsers.DataBind();
        }
    }
}